package com.dong.es.entity;

import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import com.dong.es.entity.searchparam.agg.EsAggsParam;
import com.dong.es.entity.searchparam.index.EsIndexParam;
import com.dong.es.entity.searchparam.order.EsSortParam;
import com.dong.es.entity.searchparam.page.EsPageParam;
import com.dong.es.entity.searchparam.query.EsQueryParam;
import com.dong.es.entity.searchparam.source.EsSourceParam;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @description: ES 公共的参数接收实体类
 * @author: 陈瑞东
 * @create: 2022-05-20 10:22
 */
public class EsBaseDTO implements Serializable {
    private static final long serialVersionUID = 7367835688384869286L;

    // 查询索引
    private EsIndexParam index;

    // 分页参数
    private EsPageParam page;

    // 排序参数
    private List<EsSortParam> sort;

    // 字段显示参数
    private EsSourceParam source;

    // 查询参数
    private List<EsQueryParam> query;

    // 聚合参数
    private EsAggsParam aggregations;



    public void index(EsIndexParam index) {
        this.index = index;
    }

    public void page(EsPageParam page) {
        this.page = page;
    }

    public void sort(EsSortParam sort) {
        if (this.sort == null) {
            this.sort = new ArrayList<>();
        }
        this.sort.add(sort);
    }

    public void source(EsSourceParam source) {
        this.source = source;
    }

    public void query(EsQueryParam query) {
        if (this.query == null) {
            this.query = new ArrayList<>();
        }
        this.query.add(query);
    }

    /**
     * 解析聚合
     * @param aggregateMap 聚合值
     * @param clazz 解析聚合的类型
     * @return 解析后的数据
     */
    public <T> T parseAggregations(Map<String, Aggregate> aggregateMap, Class<? extends EsAggsParam<T>> clazz) {
        if (aggregateMap != null && !aggregateMap.isEmpty()) {
            return (T) aggregations.parseResult(aggregateMap);
        }
        return null;
    }


    public void aggregations(EsAggsParam aggregations) {
        this.aggregations = aggregations;
    }

    public List<EsSortParam> getSort() {
        return sort;
    }

    public void setSort(List<EsSortParam> sort) {
        this.sort = sort;
    }

    public List<EsQueryParam> getQuery() {
        return query;
    }

    public void setQuery(List<EsQueryParam> query) {
        this.query = query;
    }

    public EsAggsParam getAggregations() {
        return aggregations;
    }
    /**
     * 生成查询数据
     */
    public SearchRequest.Builder generator() {
        SearchRequest.Builder builder = new SearchRequest.Builder();

        builder.trackTotalHits(trackTotalHits -> trackTotalHits.enabled(true));

        if (index != null) {
            index.loadTo(builder);
        }
        if (page != null) {
            page.loadTo(builder);
        }
        if (query != null) {
            builder.query(query -> query.bool(bool -> {
                for (EsQueryParam esQueryParam : this.query) {
                    esQueryParam.loadTo(bool);
                }
                return bool;
            }));
        }
        if (sort != null) {
            for (EsSortParam esSortParam : sort) {
                esSortParam.loadTo(builder);
            }
        }
        if (source != null) {
            builder.source(source -> source.filter(filter -> {
                this.source.loadTo(filter);
                return filter;
            }));
        }

        if (aggregations != null) {
            this.aggregations.loadTo(builder);
        }

        return builder;
    }



    /**
     * 字段名称，限制方法
     */
    public static interface Field {
        public String field();
        public Class type();
    }
}
